package wechat.handler.request.base;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import wechat.handler.bean.request.RequestResultBean;
import wechat.handler.resources.AppFilter;
import wechat.handler.resources.InstanceResource;
import wechat.handler.util.Configure;
import wechat.handler.util.RedisUtil;
import wechat.handler.util.RespCode;
import wechat.handler.util.http.HttpClientUtil;

public class BaseRequest {
	private Logger log = LoggerFactory.getLogger(BaseRequest.class);
	
	protected static final String Appid = Configure.getAppid() ;
	protected static final String Appsecret = Configure.getAppsecret() ;
	protected static Configure INS = Configure.getInstans();
	
	
	private int Deadline = 7100;
	private RedisUtil redisUtil = RedisUtil.getInstans();
	
	private static String PREFIX_Token = "wechat:token:";
	private static String PREFIX_JSTicket = "wechat:JSTicket:";
	private static final String WechatAccessToken = PREFIX_Token + Appid;
	private static final String WechatJSTicket = PREFIX_JSTicket + Appid;
	
	
	//取得access_token
	private String api_access_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	//取得微信服务器IP
	private String api_wechat_ip = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN";
	
	//创建菜单
	protected String api_menu_create = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";

	//设置模板行业
	protected String api_set_industry = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN";
	//获取模板行业
	protected String api_get_industry = "https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token=ACCESS_TOKEN";
	//添加模板，即获得长id
	protected String api_add_template = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=ACCESS_TOKEN";
	//获得所有模板
	protected String api_all_template = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=ACCESS_TOKEN";
	//发送模板
	protected String api_send_template = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";

	//用户网页授权
	protected String api_sns_accesstoken = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	
	//获取JSticket
	protected String api_get_jsticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	
	protected String getAccessToken() throws Exception {
		String access_token = null;
		if (!redisUtil.exists(WechatAccessToken)) {

			String url = this.api_access_token.replace("APPID", Appid).replace("APPSECRET",Appsecret);
			String result = HttpClientUtil.get(url);
			JSONObject jsonResult = JSONObject.parseObject(result);

			checkResult(jsonResult);

			System.out.println("access_token :" + jsonResult.getString("access_token"));
			System.out.println("expires_in :" + jsonResult.get("expires_in"));
			log.info("BaseRequest--getAccessToken access_token=" + jsonResult.getString("access_token") + " expires_in=" + jsonResult.get("expires_in"));

			access_token = jsonResult.getString("access_token");
	
			redisUtil.setex(WechatAccessToken, Deadline, access_token);
			
			return access_token;
		}

		
		access_token = redisUtil.get(WechatAccessToken);
		log.info("BaseRequest--getAccessToken Get AccessToken from redis  access_token=" + access_token);
		
		return access_token;
	}
	
	
	protected String getAccessToken(String appid) throws Exception {
		log.info("BaseRequest--getAccessToken appid=" + appid);
		
		String access_token = null;
		String tokenKey = PREFIX_Token + appid;
		
		if (!redisUtil.exists(tokenKey)) {
			InstanceResource instanceResource = AppFilter.chooseApp(appid);
			
			//String url = this.api_access_token.replace("APPID", INS.getValue(appid + ".appid")).replace("APPSECRET",INS.getValue(appid + ".appsecret"));
			String url = this.api_access_token.replace("APPID", instanceResource.getAppid()).replace("APPSECRET",instanceResource.getAppsecret());
			String result = HttpClientUtil.get(url);
			JSONObject jsonResult = JSONObject.parseObject(result);

			checkResult(jsonResult);

			System.out.println("access_token :" + jsonResult.getString("access_token"));
			System.out.println("expires_in :" + jsonResult.get("expires_in"));
			log.info("BaseRequest--getAccessToken access_token=" + jsonResult.getString("access_token") + " expires_in=" + jsonResult.get("expires_in"));

			access_token = jsonResult.getString("access_token");
	
			redisUtil.setex(tokenKey, Deadline, access_token);
			
			return access_token;
		}

		access_token = redisUtil.get(tokenKey);
		log.info("BaseRequest--getAccessToken Get AccessToken from redis  access_token=" + access_token);
		
		return access_token;
	}
	
	protected String getJSTicket() throws Exception {
		String ticket = null;
		if (!redisUtil.exists(WechatJSTicket)) {

			String url = this.api_get_jsticket.replace("ACCESS_TOKEN", getAccessToken());
			String result = HttpClientUtil.get(url);
			
			JSONObject jsonResult = JSONObject.parseObject(result);
			checkResult(jsonResult);

			log.info("BaseRequest--getJSTicket ticket=" + jsonResult.getString("ticket") + " expires_in=" + jsonResult.get("expires_in"));

			ticket = jsonResult.getString("ticket");
	
			redisUtil.setex(WechatJSTicket, Deadline, ticket);
			
			return ticket;
		}

		ticket = redisUtil.get(WechatJSTicket);
		log.info("BaseRequest--getJSTicket Get JSTicket from redis  ticket=" + ticket);
		
		return ticket;

	}
	
	protected String getJSTicket(String appid) throws Exception {
		String ticket = null;
		String jsTicketKey = PREFIX_JSTicket + appid;
		
		if (!redisUtil.exists(jsTicketKey)) {

			String url = this.api_get_jsticket.replace("ACCESS_TOKEN", getAccessToken(appid));
			String result = HttpClientUtil.get(url);
			
			JSONObject jsonResult = JSONObject.parseObject(result);
			checkResult(jsonResult);

			log.info("BaseRequest--getJSTicket ticket=" + jsonResult.getString("ticket") + " expires_in=" + jsonResult.get("expires_in"));

			ticket = jsonResult.getString("ticket");
	
			redisUtil.setex(jsTicketKey, Deadline, ticket);
			
			return ticket;
		}

		ticket = redisUtil.get(jsTicketKey);
		log.info("BaseRequest--getJSTicket Get JSTicket from redis  ticket=" + ticket);
		
		return ticket;

	}
	
	protected void resetAccessToken() throws Exception {
		String access_token = null;

		String url = this.api_access_token.replace("APPID", Appid).replace("APPSECRET", Appsecret);
		String result = HttpClientUtil.get(url);
		JSONObject jsonResult = JSONObject.parseObject(result);

		checkResult(jsonResult);

		System.out.println("access_token :" + jsonResult.getString("access_token"));
		System.out.println("expires_in :" + jsonResult.get("expires_in"));
		log.info("BaseRequest--resetAccessToken access_token=" + jsonResult.getString("access_token") + " expires_in=" + jsonResult.get("expires_in"));

		access_token = jsonResult.getString("access_token");

		redisUtil.setex(WechatAccessToken, Deadline, access_token);
	}
	
	
	protected void resetAccessToken(String appid) throws Exception {
		log.info("BaseRequest--resetAccessToken appid=" + appid);
		String access_token = null;
		String tokenKey = PREFIX_Token + appid;
		
		InstanceResource instanceResource = AppFilter.chooseApp(appid);
		
		//String url = this.api_access_token.replace("APPID", INS.getValue(appid + ".appid")).replace("APPSECRET",INS.getValue(appid + ".appsecret"));
		String url = this.api_access_token.replace("APPID", instanceResource.getAppid()).replace("APPSECRET",instanceResource.getAppsecret());
		String result = HttpClientUtil.get(url);
		JSONObject jsonResult = JSONObject.parseObject(result);

		checkResult(jsonResult);

		System.out.println("access_token :" + jsonResult.getString("access_token"));
		System.out.println("expires_in :" + jsonResult.get("expires_in"));
		log.info("BaseRequest--resetAccessToken access_token=" + jsonResult.getString("access_token") + " expires_in=" + jsonResult.get("expires_in"));

		access_token = jsonResult.getString("access_token");

		redisUtil.setex(tokenKey, Deadline, access_token);
	}
	
	protected void resetJSTicket() throws Exception {
		String ticket = null;

		String url = this.api_get_jsticket.replace("ACCESS_TOKEN", getAccessToken());
		String result = HttpClientUtil.get(url);

		JSONObject jsonResult = JSONObject.parseObject(result);
		checkResult(jsonResult);

		log.info("BaseRequest--resetJSTicket ticket=" + jsonResult.getString("ticket") + " expires_in=" + jsonResult.get("expires_in"));

		ticket = jsonResult.getString("ticket");

		redisUtil.setex(WechatJSTicket, Deadline, ticket);
	}
	
	protected void resetJSTicket(String appid) throws Exception {
		String ticket = null;
		String jsTicketKey = PREFIX_JSTicket + appid;
		
		String url = this.api_get_jsticket.replace("ACCESS_TOKEN", getAccessToken(appid));
		String result = HttpClientUtil.get(url);

		JSONObject jsonResult = JSONObject.parseObject(result);
		checkResult(jsonResult);

		log.info("BaseRequest--resetJSTicket ticket=" + jsonResult.getString("ticket") + " expires_in=" + jsonResult.get("expires_in"));

		ticket = jsonResult.getString("ticket");

		redisUtil.setex(jsTicketKey, Deadline, ticket);
	}
	

	protected List<String> getWechatIp() throws Exception {
		String url = this.api_wechat_ip.replace("ACCESS_TOKEN", getAccessToken());
		String result = HttpClientUtil.get(url);
		JSONObject jsonResult = JSONObject.parseObject(result);

		checkResult(jsonResult);

		System.out.println("ip_list :" + jsonResult.get("ip_list"));
		log.info("BaseRequest--getWechatIp  ip_list=" + jsonResult.get("ip_list"));
		
		JSONArray ipArray = jsonResult.getJSONArray("ip_list");
		List<String> iplist = JSON.parseArray(ipArray.toString(), String.class);

		return iplist;
	}
	
	
	
	protected void checkResult(JSONObject jsonResult) throws Exception {
		if (jsonResult == null) {
			throw new Exception("返回结果为null");
		}
		
		RequestResultBean resultBean = new RequestResultBean();
		log.info("BaseRequest--checkResult  jsonResult=" + jsonResult.toJSONString());
		
		if (jsonResult.containsKey("errcode")) {
			resultBean = JSON.parseObject(jsonResult.toJSONString(), RequestResultBean.class);
			
			int errcode = jsonResult.getIntValue("errcode");
			String errmsg = jsonResult.getString("errmsg");
			String msgid = jsonResult.getString("msgid");
			String errmsgdesc = RespCode.getMessage(errcode);
			
//			System.out.println("errcode :" + errcode);
//			System.out.println("errmsg :" + errmsg);
//			System.out.println(errmsgdesc);
			
			log.info("BaseRequest--checkResult  errcode=" + errcode + " errmsg=" + errmsg +  " msgid=" + msgid +  " errmsgdesc=" + errmsgdesc);
			
			resultBean.setErrcode(errcode);
			resultBean.setErrmsg(errmsg);
			resultBean.setMsgid(msgid);
			resultBean.setErrmsgdesc(errmsgdesc);
		}
		
		if (resultBean.getErrcode() != 0) {
			throw new Exception(resultBean.getErrcode() + " - " + resultBean.getErrmsg() + " - " + resultBean.getErrmsgdesc());
		}
	}
	
	
	public static void main(String[] args) throws Exception {
		BaseRequest baseRequest = new BaseRequest();
		System.out.println(baseRequest.getWechatIp());
//		String url = baseRequest.api_sns_accesstoken.replace("APPID", Configure.getAppid()).replace("SECRET", Configure.getAppsecret()).replace("CODE", "1");
//		System.out.println(url);
	}
}
